﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;

namespace btnet.pages
{
    public partial class svn_hook : CommonPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Bug_Util.set_context(HttpContext.Current);
            Bug_Util.do_not_cache(Response);

            string username = Request["username"];
            string password = Request["password"];

            string svn_log = Request["svn_log"];
            string repo = Request["repo"];


            if (username == null
            || username == "")
            {
                Response.AddHeader("BTNET", "ERROR: username required");
                Response.Write("ERROR: username required");
                Response.End();
            }


            if (username != Bug_Util.get_setting("SvnHookUsername", ""))
            {
                Response.AddHeader("BTNET", "ERROR: wrong username. See Web.config svnHookUsername");
                Response.Write("ERROR: wrong username. See Web.config svnHookUsernam");
                Response.End();
            }

            if (password == null
            || password == "")
            {
                Response.AddHeader("BTNET", "ERROR: password required");
                Response.Write("ERROR: password required");
                Response.End();
            }

            // authenticate user

            bool authenticated = btnet.Authenticate.check_password(username, password);

            if (!authenticated)
            {
                Response.AddHeader("BTNET", "ERROR: invalid username or password");
                Response.Write("ERROR: invalid username or password");
                Response.End();
            }


            Bug_Util.write_to_log("svn_log follows");
            Bug_Util.write_to_log(svn_log);

            Bug_Util.write_to_log("repo follows");
            Bug_Util.write_to_log(repo);


            XmlDocument doc = new XmlDocument();

            doc.LoadXml(svn_log);
            XmlNodeList revisions = doc.GetElementsByTagName("logentry");


            for (int i = 0; i < revisions.Count; i++)
            {
                XmlElement logentry = (XmlElement)revisions[i];

                string msg = logentry.GetElementsByTagName("msg")[0].InnerText;
                string bug = get_bugid_from_msg(msg);

                if (bug == "")
                {
                    bug = "0";

                }
                string revision = logentry.GetAttribute("revision");
                string author = logentry.GetElementsByTagName("author")[0].InnerText;
                string date = logentry.GetElementsByTagName("date")[0].InnerText;


                string sql = @"
declare @cnt int
select @cnt = count(1) from svn_revisions where svnrev_revision = '$svnrev_revision'

if @cnt = 0 
BEGIN
insert into svn_revisions
(
	svnrev_revision,
	svnrev_bug,
	svnrev_repository,
	svnrev_author,
	svnrev_svn_date,
	svnrev_btnet_date,
	svnrev_msg
)
values
(
	'$svnrev_revision',
	$svnrev_bug,
	N'$svnrev_repository',
	N'$svnrev_author',
	N'$svnrev_svn_date',
	getdate(),
	N'$svnrev_msg'
)

select scope_identity()
END	
ELSE
select 0
";

                sql = sql.Replace("$svnrev_revision", revision.Replace("'", "''"));
                sql = sql.Replace("$svnrev_bug", Convert.ToString(bug));
                sql = sql.Replace("$svnrev_repository", repo.Replace("'", "''"));
                sql = sql.Replace("$svnrev_author", author.Replace("'", "''"));
                sql = sql.Replace("$svnrev_svn_date", date.Replace("'", "''"));
                sql = sql.Replace("$svnrev_msg", msg.Replace("'", "''"));

                int svnrev_id = Convert.ToInt32(DbUtil.execute_scalar(sql));

                if (svnrev_id > 0)
                {
                    XmlNodeList paths = logentry.GetElementsByTagName("path");

                    for (int j = 0; j < paths.Count; j++)
                    {

                        XmlElement path_element = (XmlElement)paths[j];

                        string action = path_element.GetAttribute("action");
                        string file_path = path_element.InnerText;


                        sql = @"
insert into svn_affected_paths
(
svnap_svnrev_id,
svnap_action,
svnap_path
)
values
(
$svnap_svnrev_id,
N'$svnap_action',
N'$svnap_path'
)";

                        sql = sql.Replace("$svnap_svnrev_id", Convert.ToString(svnrev_id));
                        sql = sql.Replace("$svnap_action", action.Replace("'", "''"));
                        sql = sql.Replace("$svnap_path", file_path.Replace("'", "''"));

                        DbUtil.execute_nonquery(sql);

                    } // end for each path
                }  // if we inserted a revision
            } // end for each revision


            Response.Write("OK:");
            Response.End();
        }


        string get_bugid_from_msg(string msg)
        {
            string without_line_breaks = msg.Replace("\r\n", "").Replace("\n", "");

            Regex reIntegerAtEnd = new Regex("([0-9]+$)");
            Match m = reIntegerAtEnd.Match(without_line_breaks);

            if (m.ToString() != "")
            {
                return m.ToString();
            }
            else
            {
                Regex reIntegerAtStart = new Regex("(^[0-9]+)");
                Match m2 = reIntegerAtStart.Match(without_line_breaks);
                return m2.ToString();
            }
        }
    }
}
